{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from __future__ import absolute_import\n",
    "from __future__ import print_function\n",
    "import numpy as np\n",
    "np.random.seed(1337)  # for reproducibility\n",
    "\n",
    "\n",
    "import random\n",
    "from keras.models import Sequential, Model\n",
    "from keras.layers import Dense, Dropout, Input, Lambda, Activation, Flatten\n",
    "from keras.layers import Convolution2D, MaxPooling2D,BatchNormalization, AveragePooling2D\n",
    "from keras.regularizers import l2, activity_l2\n",
    "from keras.optimizers import RMSprop,Adagrad\n",
    "\n",
    "\n",
    "from keras.applications.resnet50 import ResNet50\n",
    "from keras.preprocessing import image\n",
    "from keras.applications.resnet50 import preprocess_input, decode_predictions\n",
    "\n",
    "#from keras.metrics import kullback_leibler_divergence\n",
    "from keras import backend as K\n",
    "from datasets.tidr import load_data\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "too many indices for array",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-3e2683e8ac4b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     94\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     95\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 96\u001b[0;31m \u001b[0mall_pairs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcreate_compare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDistortImg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mRefImg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     97\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     98\u001b[0m \u001b[0mX_train\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mall_pairs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2001\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-2-3e2683e8ac4b>\u001b[0m in \u001b[0;36mcreate_compare\u001b[0;34m(x_train, x_ref)\u001b[0m\n\u001b[1;32m     40\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m25\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     41\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m120\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 42\u001b[0;31m             \u001b[0mx1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpreprocess_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_train\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m120\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     43\u001b[0m             \u001b[0mx2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpreprocess_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_ref\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     44\u001b[0m             \u001b[0mpairs\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/rwa56/homebrew/lib/python2.7/site-packages/keras/applications/imagenet_utils.pyc\u001b[0m in \u001b[0;36mpreprocess_input\u001b[0;34m(x, dim_ordering)\u001b[0m\n\u001b[1;32m     32\u001b[0m     \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     33\u001b[0m         \u001b[0;31m# 'RGB'->'BGR'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 34\u001b[0;31m         \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     35\u001b[0m         \u001b[0;31m# Zero-center by mean pixel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     36\u001b[0m         \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-=\u001b[0m \u001b[0;36m103.939\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mIndexError\u001b[0m: too many indices for array"
     ]
    }
   ],
   "source": [
    "def euclidean_distance(vects):\n",
    "    x, y = vects\n",
    "    testK =  K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True)) / 100\n",
    "    return testK\n",
    "\n",
    "def eucl_dist_output_shape(shapes):\n",
    "    shape1, shape2 = shapes\n",
    "    return (shape1[0], 1)\n",
    "\n",
    "\n",
    "def contrastive_loss(y_true, y_pred):\n",
    "    '''Contrastive loss from Hadsell-et-al.'06\n",
    "    http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf\n",
    "    '''\n",
    "    margin = 1\n",
    "    return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))\n",
    "\n",
    "\n",
    "def create_pairs(x, digit_indices):\n",
    "    '''Positive and negative pair creation.\n",
    "    Alternates between positive and negative pairs.\n",
    "    '''\n",
    "    pairs = []\n",
    "    labels = []\n",
    "    n = min([len(digit_indices[d]) for d in range(10)]) - 1\n",
    "    for d in range(10):\n",
    "        for i in range(n):\n",
    "            z1, z2 = digit_indices[d][i], digit_indices[d][i + 1]\n",
    "            pairs += [[x[z1], x[z2]]]\n",
    "            inc = random.randrange(1, 10)\n",
    "            dn = (d + inc) % 10\n",
    "            z1, z2 = digit_indices[d][i], digit_indices[dn][i]\n",
    "            pairs += [[x[z1], x[z2]]]\n",
    "            labels += [1, 0]\n",
    "    return np.array(pairs), np.array(labels)\n",
    "\n",
    "def create_compare(x_train, x_ref):\n",
    "    pairs = []\n",
    "    labels = []\n",
    "    for i in xrange(25):\n",
    "        for j in xrange(120):\n",
    "            x1 = x_train[120*i+j]\n",
    "            x2 = x_ref[i]\n",
    "            pairs += [[x1, x2]]\n",
    "            #pairs += [[x_train[120*i+j], x_ref[i]]]\n",
    "\n",
    "    return np.array(pairs)\n",
    "\n",
    "\n",
    "\n",
    "def create_base_network(input_shape):\n",
    "    '''Base network to be shared (eq. to feature extraction).\n",
    "    '''\n",
    "    seq = Sequential()\n",
    "\n",
    "    seq.add(Convolution2D(32, 5, 5, border_mode='same',\n",
    "                input_shape=input_shape))\n",
    "    seq.add(Activation('relu'))\n",
    "    seq.add(Convolution2D(32, 5, 5))\n",
    "    seq.add(BatchNormalization())\n",
    "    seq.add(Activation('relu'))\n",
    "    seq.add(MaxPooling2D(pool_size=(5, 5), strides=(2, 2)))\n",
    "    seq.add(Dropout(0.25))\n",
    "    seq.add(Convolution2D(64, 3, 3))\n",
    "    seq.add(BatchNormalization())\n",
    "    seq.add(Activation('relu'))\n",
    "    seq.add(Convolution2D(64, 3, 3))\n",
    "    seq.add(BatchNormalization())\n",
    "    seq.add(Activation('relu'))\n",
    "    seq.add(AveragePooling2D(pool_size=(2, 2),strides=(2, 2)))\n",
    "    seq.add(Dropout(0.25))\n",
    "    seq.add(Flatten())\n",
    "    seq.add(Dense(256))\n",
    "    return seq\n",
    "\n",
    "def create_res_network():\n",
    "    model = ResNet50(weights='imagenet')\n",
    "\n",
    "    return model\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "def compute_accuracy(predictions, labels):\n",
    "    '''Compute classification accuracy with a fixed threshold on distances.\n",
    "    '''\n",
    "    return labels[predictions.ravel() < 0.5].mean()\n",
    "\n",
    "\n",
    "# the data, shuffled and split between train and test sets\n",
    "DistortImg, DistortLabel, RefImg, RefLabel, ScoreLabel = load_data()\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "all_pairs = create_compare(DistortImg, RefImg)\n",
    "\n",
    "X_train = all_pairs[1:2001]\n",
    "X_test =  all_pairs[2000:]\n",
    "\n",
    "Y_train = ScoreLabel[1:2001]\n",
    "Y_test = ScoreLabel[2000:]\n",
    "\n",
    "Y_quant = DistortLabel\n",
    "\n",
    "input_dim = 224,224\n",
    "nb_epoch = 10\n",
    "input_shape = (224,224,3)\n",
    "ScoreLabel = np.array(ScoreLabel)\n",
    "#ScoreLabel = ScoreLabel / 10\n",
    "# network definition\n",
    "base_network = create_res_network()\n",
    "\n",
    "input_a = Input(shape=input_shape)\n",
    "input_b = Input(shape=input_shape)\n",
    "\n",
    "# because we re-use the same instance `base_network`,\n",
    "# the weights of the network\n",
    "# will be shared across the two branches\n",
    "processed_a = base_network(input_a)\n",
    "processed_b = base_network(input_b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
